(function(angular) {
	'use strict';
	angular.module('fs.waf').factory('dynaparmService', dynaparmService);
	dynaparmService.$inject = [ '$q', 'loggerFactory', 'ajaxServiceFactory', '$filter'];
	function dynaparmService($q, loggerFactory, ajaxServiceFactory, $filter) {
		var log = loggerFactory.getLogger("dynaparmService");
		
		function initCtrlListFunction(ctrl){
			ctrl.changeParmCat = function(){
				ctrl.searchCriteria.parmSubcatOptions = getParmSubcatOptions(ctrl.searchCriteria.dynaparmCatList, ctrl.searchCriteria.dynaparmSubCatList, ctrl.searchCriteria.serviceCode, ctrl.searchCriteria.parmCat);
			};
			
			ctrl.changeServiceCode = function(){
				ctrl.searchCriteria.parmCatOptions = getParmCatOptions(ctrl.searchCriteria.dynaparmCatList, ctrl.searchCriteria.serviceCode);
			};
			
			ctrl.changeParmType = function(){
				ctrl.searchCriteria.parmValueUitypeOptions = getParmValueUitypeOptions(ctrl.searchCriteria.parmType);
			};
		};
		
		function initCtrlFunction(ctrl){
			ctrl.changeParmCat = function(dynaparm){
				dynaparm.parmSubcatOptions = getParmSubcatOptions(dynaparm.dynaparmCatList, dynaparm.dynaparmSubCatList, dynaparm.serviceCode, dynaparm.parmCat);
				if(dynaparm.parmSubcat){
					ctrl.changedSubCat(dynaparm);
				}
			};

			ctrl.changeServiceCode = function(dynaparm){
				dynaparm.parmCatOptions = getParmCatOptions(dynaparm.dynaparmCatList, dynaparm.serviceCode);
				dynaparm.valueBeanIdOptions = getValueBeanIdOptions(dynaparm);
			};
			
			ctrl.changedParmRequired = function(dynaparm){
				if (dynaparm.parmRequired == 'Y') {
					dynaparm.clientEditValue = 'Y';
				}
			};
			
			ctrl.changedSubCat = function(dynaparm){
				var parmCatId = getParmCatId(dynaparm.dynaparmCatList, dynaparm.serviceCode, dynaparm.parmCat);
				angular.forEach(dynaparm.dynaparmSubCatList, function(data, index, array){
					if(data.parmCatId == parmCatId && data.parmSubcat == dynaparm.parmSubcat){
						dynaparm.dynaparmSubCatObj = data;
					}
				});
				initGrpOptions(dynaparm);
				initCompanyTypeAndParmUsage(ctrl, dynaparm);
			};
			
			ctrl.changedGrp1 = function(dynaparm){
				dynaparm.parmGrp1Name = getValueFromList(dynaparm.parmGrp1Options, dynaparm.parmGrp1Value);
			};
			
			ctrl.changedGrp2 = function(dynaparm){
				dynaparm.parmGrp2Name = getValueFromList(dynaparm.parmGrp2Options, dynaparm.parmGrp2Value);
			};
			
			ctrl.changedGrp3 = function(dynaparm){
				dynaparm.parmGrp3Name = getValueFromList(dynaparm.parmGrp3Options, dynaparm.parmGrp3Value);
			};
			
			ctrl.changeParmType = function(dynaparm, formCtrl, isInitialized){
				if(isInitialized){
					return;
				}
				dynaparm.parmLen = "";
				ctrl.changeParmTypeSubFun(dynaparm);
			};
			
			ctrl.changeParmTypeSubFun = function(dynaparm){
				dynaparm.parmValueUitypeOptions = getParmValueUitypeOptions(dynaparm.parmType);
				dynaparm.formatOptions = getFormatOptions(dynaparm.parmType, dynaparm.formatList);
				dynaparm.parmValidationOptions = getParmValidationOptions(dynaparm.parmType);
				if(dynaparm.parmType == "java.util.Date" || dynaparm.parmType == "java.sql.Date" 
					|| dynaparm.parmType == "java.sql.Timestamp" || dynaparm.parmType == "java.sql.Time"){
					dynaparm.parmValidate = '';
				}
				if( dynaparm.parmType == "java.util.Date" 
					|| dynaparm.parmType == "java.sql.Date" || dynaparm.parmType == "java.sql.Timestamp" 
						|| dynaparm.parmType == "java.sql.Time"){
					dynaparm.parmLen_show = false;
					dynaparm.parmFormat_show = true;
				}else{
					dynaparm.parmLen_show = true;
					dynaparm.parmFormat_show = false;
				}
				dynaparm.parmValidate_show = isShowParmValidate(dynaparm);
				dynaparm.parmLen_show = isShowParmLength(dynaparm);
			}
			
			ctrl.changeParmValueUitype = function(dynaparm){
				dynaparm.parmLen = dynaparm.parmLen || "";
				dynaparm.valueBeanIdOptions = getValueBeanIdOptions(dynaparm);
				if(dynaparm.parmValueUitype != "I"){
					dynaparm.parmValidate = '';
				}
				dynaparm.parmLen_show = isShowParmLength(dynaparm);
				dynaparm.parmValidate_show = isShowParmValidate(dynaparm);
			};
			
			ctrl.isShowDropDown = function(){
				if(ctrl.dynaparm && ctrl.dynaparm.parmValueUitype == 'L'){
					return true;
				}else{
					return false;
				}
			};
		};
		
		function getValueBeanIdOptions(dynaparm){
			var serviceCode = dynaparm.serviceCode;
			var parmValueUitype = dynaparm.parmValueUitype;
			if(!serviceCode || !parmValueUitype){
				return [];
			}
			var valueBeanIdOptions = [];
			angular.forEach(dynaparm.dynaValueBeanList, function(data, index, array){
				var beanType = '';
				if(parmValueUitype == "D"){
					beanType = "JAVA";
					
				}else if(parmValueUitype == "S"){
					beanType = "POPUP";
				}
				if(data.beanType == beanType && (data.serviceCode == '*' || data.serviceCode == serviceCode)){
					var opt = new Object();
					opt.value = parseInt(data.valueBeanId);
					opt.label = data.valueBeanName;
					valueBeanIdOptions.push(opt);
				}
			});
			if(dynaparm.parmValueUitype == 'D' || dynaparm.parmValueUitype == 'S'){
				if(!dynaparm.valueBeanId || !isExist(valueBeanIdOptions, dynaparm.valueBeanId)){
					dynaparm.valueBeanId = valueBeanIdOptions[0] ? valueBeanIdOptions[0].value : "";
				}
			}else{
				dynaparm.valueBeanId = "";
			}
			return valueBeanIdOptions;
		};
		
		function isExist(list, data){
			if(list && list.length > 0){
				for (var i = 0; i < list.length; i++) {
					if(list[i].value == data){
						return true;
					}
				}
			}
			return false;
		};
		
		function isShowParmValidate(dynaparm){
			if(dynaparm.parmValueUitype != "I"){
				return false;
			}else{
				if(dynaparm.parmType == "java.util.Date" || dynaparm.parmType == "java.sql.Date" || dynaparm.parmType == "java.lang.Float"
					|| dynaparm.parmType == "java.sql.Timestamp" || dynaparm.parmType == "java.sql.Time"){
					return false;
				}
				return true;
			}
		};
		
		function isShowParmLength (dynaparm){
			if(dynaparm.parmValueUitype == "E"){
				return true;
			} else if(dynaparm.parmValueUitype != "I"){
				return false;
			}else if (dynaparm.parmType == "java.util.Date" || dynaparm.parmType == "java.sql.Date" 
					|| dynaparm.parmType == "java.sql.Timestamp" || dynaparm.parmType == "java.sql.Time" || dynaparm.parmType == "java.lang.Char"){
					return false;
			}
			return true;
		}
		
		function initCompanyTypeAndParmUsage(ctrl, dynaparm){
			if(dynaparm.dynaparmSubCatObj){
				if(dynaparm.dynaparmSubCatObj.usageCfg && dynaparm.parmCat && dynaparm.parmSubcat){
					var usagesCfgInfo = getCfgInfo(dynaparm.dynaparmSubCatObj.usageCfg);
					if(dynaparm.dynaparmSubCatObj.usageFlag == 'Y'){
						if(usagesCfgInfo.multiple == 'Y'){
							ctrl.parmUsageList_show = true;
							ctrl.parmUsage_show = false;
						}else{
							ctrl.parmUsageList_show = false;
							ctrl.parmUsage_show = true;
						}
					}else{
						ctrl.parmUsageList_show = false;
						ctrl.parmUsage_show = false;
					}
					ctrl.parmusageOptions = usagesCfgInfo.optionList;
				}else{
					ctrl.parmUsageList_show = false;
					ctrl.parmUsage_show = false;
				}
				if(dynaparm.dynaparmSubCatObj.companytypeCfg && dynaparm.parmCat && dynaparm.parmSubcat){
					var companyTypeCfgInfo = getCfgInfo(dynaparm.dynaparmSubCatObj.companytypeCfg);
					if(dynaparm.dynaparmSubCatObj.companytypeFlag == 'Y'){
						if(companyTypeCfgInfo.multiple == 'Y'){
							ctrl.companyTypeList_show = true;
							ctrl.companyTypes_show = false;
						}else{
							ctrl.companyTypeList_show = false;
							ctrl.companyTypes_show = true;
						}
					}else{
						ctrl.companyTypeList_show = false;
						ctrl.companyTypes_show = false;
					}
					ctrl.companyTypeOptions = ctrl.companyTypeOptions == null ? getCompanyTypeLookupOptions(companyTypeCfgInfo.multiple) : ctrl.companyTypeOptions;
				}else{
					ctrl.parmUsageList_show = false;
					ctrl.parmUsage_show = false;
				}
			}
		}
		
		function initParmLength(dynaparm){
			if(dynaparm.parmType == "java.lang.Char"){
				dynaparm.parmLen = new Number(1);
			}
		}
		
		function parseParmLength(dynaparm){
			if(dynaparm.parmType == "java.lang.Char"){
				dynaparm.parmLen = null;
			}
		}
		
		function getFormatOptions(parmType, formatList){
			var formats = [];
			if(parmType == "java.util.Date" ){
				formats.push("date");
			}else if(parmType == "java.sql.Date"){
				formats.push("date");
			}else if( parmType == "java.sql.Timestamp"){
				formats.push("timestamp","shortTimestamp");
			}else if(parmType == "java.sql.Time"){
				formats.push("time", "shortTime");
			}
			var formatListTmp = [];
			angular.forEach(formatList, function(data, index, array){
				if(contains(data.value, formats)){
					formatListTmp.push(data);
				}
			});
			return formatListTmp;
		};
		
		function contains(obj, list){
			for(var i = 0; i < list.length; i++){
				if(list[i] === obj){
					return true;
				}
			}
			return false;
		};

		function initGrpOptions(dynaparm){
			if(dynaparm.dynaparmSubCatObj){
				if(getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp1Cfg) != null){
					dynaparm.parmGrp1Options = getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp1Cfg).optionList;
					if(!dynaparm.parmGrp1Value || !isExist(dynaparm.parmGrp1Options, dynaparm.parmGrp1Value)){
						dynaparm.parmGrp1Value = dynaparm.parmGrp1Options[0] ? dynaparm.parmGrp1Options[0].value : "";
						dynaparm.parmGrp1Name = getValueFromList(dynaparm.parmGrp1Options, dynaparm.parmGrp1Value);
					}
				}
				if(getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp2Cfg) != null){
					dynaparm.parmGrp2Options = getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp2Cfg).optionList;
					parmGrp2OptionsAddEmpty(dynaparm);
				}
				if(getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp3Cfg) != null){
					dynaparm.parmGrp3Options = getGrpCfgInfo(dynaparm.dynaparmSubCatObj.grp3Cfg).optionList;
					if(!dynaparm.parmGrp3Value || !isExist(dynaparm.parmGrp3Options, dynaparm.parmGrp3Value)){
						dynaparm.parmGrp3Value = dynaparm.parmGrp3Options[0] ? dynaparm.parmGrp3Options[0].value : "";
						dynaparm.parmGrp3Name = getValueFromList(dynaparm.parmGrp3Options, dynaparm.parmGrp3Value);
					}
				}
			}
		};
		
		function parmGrp2OptionsAddEmpty(dynaparm){
			if(dynaparm.parmGrp2Options){
				if(dynaparm.parmCat == 'SITESYSTEMCONFIG' || dynaparm.parmCat == 'APCUSTOMERPROFILE'
					|| (dynaparm.parmCat == 'COMPANY' && dynaparm.parmSubcat == 'CUSTOMERPROFILE')){
					if(!dynaparm.parmGrp2Value || !isExist(dynaparm.parmGrp1Options, dynaparm.parmGrp1Value)){
						dynaparm.parmGrp2Value = dynaparm.parmGrp2Options[0] ? dynaparm.parmGrp2Options[0].value : "";
						dynaparm.parmGrp2Name = getValueFromList(dynaparm.parmGrp2Options, dynaparm.parmGrp2Value);
					}
				}else{
					dynaparm.parmGrp2Options.unshift({"value" : "", "label" : ""});
				}
			}
		}
		
		function getCompanyTypeLookupOptions(multiple){
			var options = {};
			if(multiple == 'Y'){
				options = {
					"id" : "cda.companyType",
					"params" : {
						"filterCompanyTypes" : "<companyTypeList",
						"multiSelect": "true",
						"isNeedSite" : "true"
					},
					"boundTo" : {
						"companyType" : "value"
					},
					"okEvent" : true,
					"cancelEvent" : false
				};
			}else{
				options = {
					"id" : "cda.companyType",
					"params" : {
						"filterCompanyTypes" : "<companyTypes",
						"multiSelect": "false",
						"isNeedSite" : "true"
					},
					"boundTo" : {
						"companyType" : "companyTypes"
					},
					"okEvent" : true,
					"cancelEvent" : false
				};
			}
			return options;
		}
		
		function getGrpCfgInfo(grpCfg){
			if(!grpCfg){
				return null;
			}
			var list = getListFromString(grpCfg);
			var options = {};
			var i = 1;
			options.optionList = [];
			while(i > 0){
				var name = getValueFromList(list, 'NAME' + i);
				var value = getValueFromList(list, 'VALUE' + i);
				if(name && value){
					options.optionList.push({"value" : value, "label" : name});
					i++;
				}else{
					i = -1;
				}
				
			}
			return options;
		};
		
		function getCfgInfo(usageCfg){
			if(!usageCfg){
				return null;
			}
			var list = getListFromString(usageCfg);
			var options = {};
			angular.forEach(list, function(data, index, array){
				if(data.value == 'MULTIPLE'){
					options.multiple = data.label;
				}else if(data.value == 'VALUEDELIMITER'){
					options.valueDelimiter = data.label;
				}
			});
			var i = 1;
			options.optionList = {
				data : []
			};
			while(i > 0){
				var value = getValueFromList(list, 'VALUE' + i);
				var key = "";
				if(value){
					key = getValueFromList(list, 'VALUERESKEY' + i);
					i++;
					options.optionList.data.push({"value" : value, "label" : key});
				}else{
					i = -1;
				}
			}
			return options;
		};
		
		function getValueFromList(list, value){
			var result = null;
			angular.forEach(list, function(data, index, array){
				if(result == null && data.value == value){
					result = data.label;
				}
			});
			return result;
		}
		
		function getListFromString(parmValues){
			var strs = [];
			var list = [];
			if(parmValues && angular.isString(parmValues)){
				if (parmValues.indexOf("\r\n") != -1) {
					strs = parmValues.split("\r\n");
				} else if (parmValues.indexOf("\r") != -1) {
					strs = parmValues.split("\r");
				} else {
					strs = parmValues.split("\n");
				}
				if (strs != null) {
					angular.forEach(strs, function(string, index, array){
						var entry = string.split("=");
						if (entry != null && entry.length == 2) {
							list.push({
								"value" : entry[0],
								"label" : entry[1]
							});
						}else if(entry != null && entry.length == 1){
							list.push({
								"value" : entry[0],
								"label" : ""
							});
						}
					});
				}
			}
			return list;
		}
		
		function getParmValueUitypeOptions(parmType) {
			var option1 = [ {
					"value" : "I",
					"label" : "label.dynaparm.parmvaluetype.input"
				}, {
					"value" : "L",
					"label" : "label.dynaparm.parmvaluetype.dropdown"
				}, {
					"value" : "D",
					"label" : "label.dynaparm.parmvaluetype.dynadropdown"
				}, {
					"value" : "S",
					"label" : "label.dynaparm.parmvaluetype.lookup"
				}, {
					"value" : "P",
					"label" : "label.dynaparm.parmvaluetype.password"
				} ];
			var option2 = [ {
					"value" : "I",
					"label" : "label.dynaparm.parmvaluetype.input"
				}];
			var option3 = [ {
					"value" : "I",
					"label" : "label.dynaparm.parmvaluetype.input"
				}, {
					"value" : "E",
					"label" : "label.dynaparm.parmvaluetype.percentage"
				}];
			if(parmType == "java.lang.String"){
				return option1;
			} else if(parmType == "" || parmType == null){
				return [];
			} else if(parmType == "java.lang.Double" || parmType == "java.lang.Float" || parmType == "java.math.BigDecimal"){
				return option3;
			} else{
				return option2;
			}
		}
		
		//get parmValidation options by parmType
		function getParmValidationOptions(parmType) {
			var option1 = [ {
					"value" : "^[0-9]+$",
					"label" : "^[0-9]+$"
				}, {
					"value" : "^[0-9.]+$",
					"label" : "^[0-9.]+$"
				}];
			var option2 = [{
					"value" : "^[A-Za-z]+$",
					"label" : "^[A-Za-z]+$"
				}, {
					"value" : "^[0-9a-zA-Z-_]+$",
					"label" : "^[0-9a-zA-Z-_]+$"
				}];
			if(parmType == "java.lang.Double" || parmType == "java.lang.Float" || parmType == "java.lang.Integer" || parmType == "java.lang.Long" 
				|| parmType == "java.lang.Short" ||parmType == "java.lang.Byte" || parmType == "java.math.BigDecimal" ||parmType == "java.math.BigInteger"){
				return option1;
			} else if (parmType == "java.lang.String"){
				return option2;
			} else {
				return [];
			}
		}
		
		function getParmCatOptions(list, serviceCode) {
			var labelBean = [];
			serviceCode = $filter('encode')(serviceCode);
			angular.forEach(list, function(data, index, array){
				if(serviceCode == data.serviceCode){
					var labelItem = {
						"value" : data.parmCat,
						"label" : data.parmCatDesc
					};
					labelBean.push(labelItem);
				}
			});
			return labelBean;
		}
		
		function getParmCatId(catList, serviceCode, cat) {
			var catId = 0;
			serviceCode = $filter('encode')(serviceCode);
			angular.forEach(catList, function(data, index, array){
				if(data.parmCat == cat && data.serviceCode == serviceCode){
					catId = data.parmCatId;
				}
			});
			return catId;
		}
		
		function getParmSubcatOptions(parmCatList, parmSubCatList, serviceCode, cat) {
			var catId = getParmCatId(parmCatList, serviceCode, cat);
			var labelBean = [];
			angular.forEach(parmSubCatList, function(data, index, array){
				if(data.parmCatId == catId){
					var labelItem = {
						"value" : data.parmSubcat,
						"label" : data.parmSubcatDesc
					};
					if(labelItem.value == "*"){
						labelBean.unshift(labelItem);
					}else{
						labelBean.push(labelItem);
					}
				}
			});
			return labelBean;
		}
		
		return {
			initCtrlListFunction : initCtrlListFunction,
			initCtrlFunction : initCtrlFunction,
			getCompanyTypeLookupOptions : getCompanyTypeLookupOptions,
			initParmLength : initParmLength,
			parseParmLength : parseParmLength

		};
	}
})(angular);